package com.sergio.accounting.service.impl;

import com.sergio.accounting.entity.Account;
import com.sergio.accounting.repository.AccountRepository;
import com.sergio.accounting.service.AccountService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 账户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

    private final AccountRepository accountRepository;

    @Override
    public List<Account> getUserAccounts(Long userId) {
        return accountRepository.findByUserIdAndEnabledTrueOrderBySortOrderAsc(userId);
    }

    @Override
    public List<Account> getAllUserAccounts(Long userId) {
        return accountRepository.findByUserIdOrderBySortOrderAsc(userId);
    }

    @Override
    public Account getAccountById(Long accountId, Long userId) {
        return accountRepository.findByIdAndUserId(accountId, userId)
                .orElseThrow(() -> new RuntimeException("账户不存在或无权访问"));
    }

    @Override
    @Transactional
    public Account createAccount(Account account) {
        return accountRepository.save(account);
    }

    @Override
    @Transactional
    public Account updateAccount(Long accountId, Account account, Long userId) {
        Account existingAccount = getAccountById(accountId, userId);
        
        existingAccount.setName(account.getName());
        existingAccount.setAccountType(account.getAccountType());
        existingAccount.setDescription(account.getDescription());
        existingAccount.setIcon(account.getIcon());
        existingAccount.setColor(account.getColor());
        existingAccount.setInitialBalance(account.getInitialBalance());
        existingAccount.setSortOrder(account.getSortOrder());
        existingAccount.setIncludeInTotal(account.getIncludeInTotal());
        
        return accountRepository.save(existingAccount);
    }

    @Override
    @Transactional
    public void deleteAccount(Long accountId, Long userId) {
        Account account = getAccountById(accountId, userId);
        
        // 不允许删除"不计入账户"类型的账户
        if (account.getAccountType() == Account.AccountType.NOT_COUNTED) {
            throw new RuntimeException("不能删除默认的不计入账户");
        }
        
        accountRepository.delete(account);
    }

    @Override
    @Transactional
    public Account toggleAccountStatus(Long accountId, Long userId) {
        Account account = getAccountById(accountId, userId);
        
        // 不允许禁用"不计入账户"类型的账户
        if (account.getAccountType() == Account.AccountType.NOT_COUNTED) {
            throw new RuntimeException("不能禁用默认的不计入账户");
        }
        
        account.setEnabled(!account.getEnabled());
        return accountRepository.save(account);
    }

    @Override
    @Transactional
    public Account getOrCreateNotCountedAccount(Long userId) {
        return accountRepository.findByUserIdAndAccountType(userId, Account.AccountType.NOT_COUNTED)
                .orElseGet(() -> {
                    Account notCountedAccount = new Account();
                    notCountedAccount.setUserId(userId);
                    notCountedAccount.setName("不计入账户");
                    notCountedAccount.setAccountType(Account.AccountType.NOT_COUNTED);
                    notCountedAccount.setDescription("默认账户，不计入资产统计");
                    notCountedAccount.setIcon("📝");
                    notCountedAccount.setColor("#9E9E9E");
                    notCountedAccount.setInitialBalance(BigDecimal.ZERO);
                    notCountedAccount.setCurrentBalance(BigDecimal.ZERO);
                    notCountedAccount.setSortOrder(999);
                    notCountedAccount.setEnabled(true);
                    notCountedAccount.setIncludeInTotal(false);
                    
                    return accountRepository.save(notCountedAccount);
                });
    }

    @Override
    @Transactional
    public void updateAccountBalance(Long accountId, BigDecimal amount, boolean isIncome) {
        if (accountId == null) {
            return; // 不计入账户的情况，不更新余额
        }
        
        Account account = accountRepository.findById(accountId)
                .orElseThrow(() -> new RuntimeException("账户不存在"));
        
        BigDecimal currentBalance = account.getCurrentBalance();
        BigDecimal newBalance = isIncome 
                ? currentBalance.add(amount) 
                : currentBalance.subtract(amount);
        
        // 检查余额是否足够（对于支出）
        if (!isIncome && newBalance.compareTo(BigDecimal.ZERO) < 0) {
            // 对于信用卡账户，允许负余额
            if (account.getAccountType() != Account.AccountType.CREDIT_CARD) {
                throw new RuntimeException("账户余额不足。当前余额: " + currentBalance + "，尝试支出: " + amount);
            }
        }
        
        account.setCurrentBalance(newBalance);
        accountRepository.save(account);
        log.info("账户余额更新成功: 账户ID={}, 原余额={}, 变动金额={}, 新余额={}, 是否收入={}", 
                accountId, currentBalance, amount, newBalance, isIncome);
    }

    @Override
    public BigDecimal getUserTotalBalance(Long userId) {
        return accountRepository.getTotalBalanceByUserId(userId);
    }

    @Override
    @Transactional
    public void initializeDefaultAccounts(Long userId) {
        // 检查用户是否已有账户
        long accountCount = accountRepository.countByUserIdAndEnabledTrue(userId);
        if (accountCount > 0) {
            return; // 已有账户，不需要初始化
        }
        
        // 创建默认的"不计入账户"
        getOrCreateNotCountedAccount(userId);
        
        // 创建一些常用的默认账户
        createDefaultAccount(userId, "现金", Account.AccountType.CASH, "💰", "#4CAF50", 1);
        createDefaultAccount(userId, "银行卡", Account.AccountType.BANK_CARD, "🏦", "#2196F3", 2);
        createDefaultAccount(userId, "支付宝", Account.AccountType.ALIPAY, "💙", "#1677FF", 3);
        createDefaultAccount(userId, "微信", Account.AccountType.WECHAT, "💚", "#07C160", 4);
    }
    
    private void createDefaultAccount(Long userId, String name, Account.AccountType type, 
                                    String icon, String color, int sortOrder) {
        Account account = new Account();
        account.setUserId(userId);
        account.setName(name);
        account.setAccountType(type);
        account.setIcon(icon);
        account.setColor(color);
        account.setInitialBalance(BigDecimal.ZERO);
        account.setCurrentBalance(BigDecimal.ZERO);
        account.setSortOrder(sortOrder);
        account.setEnabled(true);
        account.setIncludeInTotal(true);
        
        accountRepository.save(account);
    }

    @Override
    public boolean existsByIdAndUserId(Long accountId, Long userId) {
        return accountRepository.existsByIdAndUserId(accountId, userId);
    }

    @Override
    public Account findById(Long accountId) {
        return accountRepository.findById(accountId).orElse(null);
    }
}
